/**
 * Created by zhoumingrui on 2017/1/7.
 */
import * as utils from '../util/webgl-utils'
import shader from '../shader'
import glMatrix from 'gl-matrix'
import DOM from '../util/dom'
import ImageManager from '../render/img-prepare'
import VertexManager from '../render/vertex-prepare'
import Event from '../util/event'
import WavefrontObjLoader from '../util/obj-loader'
import Transform from '../transform/transform'

const mat4 = glMatrix.mat4;

const transform = Transform.getInstance();
var imageManager = new ImageManager();
var vertexManager = new VertexManager();
var wavefrontObjLoader = null;


class IndexController extends Event {
    constructor(options) {
        super();
        this.options = options || {}

        this.finishLoading = false;

        this.regist('vertices-load', () => {
            this.finishLoading = true;
            document.getElementById('loading').style.display = 'none';
            this.repaint();
        });

        wavefrontObjLoader = new WavefrontObjLoader({
            controller: this,
            imageManager: imageManager,
            vertexManager: vertexManager
        });

        this.registerMouseEvent();
    }

    registerMouseEvent() {
        let timeout0 = null, timeout1 = null;
        let clientX = 0, clientY = 0;
        let x = 0, y = 0, z = 0, angle = 0;
        mouse.on('wheel', (e) => {
            let wheelDelta = e.wheelDelta;
            if (!timeout0) {
                wheelDelta > 0 ? y += 8 : y -= 8;
                timeout0 = setTimeout(() => {
                    this.gl.uniformMatrix4fv(this.u_MVPMatrix, false, transform.calMatrix(angle, x, y, z));
                    this.repaint();
                    clearTimeout(timeout0);
                    timeout0 = null;
                }, 500);
            }
        });
        mouse.on('grab', 'left', (e) => {
            clientX = e.clientX;
            clientY = e.clientY;
        });
        mouse.on('drag', 'left', (e) => {
            let offsetX = e.clientX - clientX;
            let offsetZ = e.clientY - clientY;
            offsetX *= 0.01;
            offsetZ *= 0.01;
            x += offsetX;
            z += offsetZ;

            if (!timeout1 && (x != 0 || z != 0)) {
                timeout1 = setTimeout(() => {
                    this.gl.uniformMatrix4fv(this.u_MVPMatrix, false, transform.calMatrix(angle, x, y, z));
                    this.repaint();
                    clearTimeout(timeout1);
                    timeout1 = null;
                }, 500);
            }
        });
        document.getElementById('testImg').onclick = () => {
            angle += 0.05;
            this.gl.uniformMatrix4fv(this.u_MVPMatrix, false, transform.calMatrix(angle, x, y, z));
            this.repaint();
        }
    }

    prepareGL() {
        let container = document.getElementById(this.options.container);
        let canvas = DOM.create('canvas', 'cennavi-canvas', container);

        if (!canvas) {
            return null;
        }
        const gl = utils.getWebGLContext(canvas);
        this.gl = gl;
        this.width = canvas.width;
        this.height = canvas.height;

        transform.resize(this.width, this.height);

        if (!utils.initShaders(gl, shader.line.vp, shader.line.fp)) {
            console.log('init shader error');
        }

        this.u_MVPMatrix = gl.getUniformLocation(gl.program, "u_MVPMatrix");

        gl.clearColor(0.0, 1.0, 0.0, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
        gl.enable(gl.DEPTH_TEST);

        this.renderGL();

        return this;
    }

    prepareGLData() {
        wavefrontObjLoader.loadObj();
    }

    _enableAttrib(name, count, step, offset) {
        const gl = this.gl;
        gl.useProgram(gl.program);
        let a_pointer = gl.getAttribLocation(gl.program, name);
        gl.vertexAttribPointer(a_pointer, count, gl.FLOAT, false, step, offset);
        gl.enableVertexAttribArray(a_pointer);

    }

    resize(width, height) {
        const gl = this.gl;

        this.width = width * browser.devicePixelRatio;
        this.height = height * browser.devicePixelRatio;
        gl.viewport(0, 0, this.width, this.height);
    }

    renderGL() {
        const gl = this.gl;

        gl.uniformMatrix4fv(this.u_MVPMatrix, false, transform.calMatrix(0, 0, 0, 0));
        const count = this.prepareGLData();
    }

    repaint() {
        const gl = this.gl;

        gl.clearColor(0.0, 1.0, 1.0, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        if (this.finishLoading) {
            wavefrontObjLoader.rerender();
        }
    }

    getGL() {
        return this.gl;
    }

}

module.exports = IndexController;